home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / sipp / libsipp / phong.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-03  |  3.2 KB  |  101 lines

  1. /**
  2.  ** sipp - SImple Polygon Processor
  3.  **
  4.  **  A general 3d graphic package
  5.  **
  6.  **  Copyright Equivalent Software HB  1992
  7.  **
  8.  ** This program is free software; you can redistribute it and/or modify
  9.  ** it under the terms of the GNU General Public License as published by
  10.  ** the Free Software Foundation; either version 1, or any later version.
  11.  ** This program is distributed in the hope that it will be useful,
  12.  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  ** GNU General Public License for more details.
  15.  ** You can receive a copy of the GNU General Public License from the
  16.  ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  **/
  18.  
  19. /**
  20.  ** phong_shader.c - The traditional Phong shading function.
  21.  **/
  22.  
  23. #include <math.h>
  24.  
  25. #include <sipp.h>
  26. #include <geometric.h>
  27. #include <shaders.h>
  28.  
  29.  
  30. void
  31. phong_shader(pos, normal, texture, view_vec, lights, pd, color, opacity)
  32.     Vector      *pos;
  33.     Vector      *normal;
  34.     Vector      *texture;
  35.     Vector      *view_vec;
  36.     Lightsource *lights;
  37.     Phong_desc  *pd;
  38.     Color       *color;
  39.     Color       *opacity;
  40. {
  41.     Vector       unit_norm;
  42.     Vector       light_dir;
  43.     Vector       specular;
  44.     Color        diffsum;
  45.     Color        specsum;
  46.     double       cos_theta;
  47.     double       cos_alpha;
  48.     double       light_fraction;
  49.     double       spec_factor;
  50.     Lightsource *lp;
  51.  
  52.     VecCopy(unit_norm, *normal);
  53.     vecnorm(&unit_norm);
  54.     diffsum.red = diffsum.grn = diffsum.blu = 0.0;
  55.     specsum.red = specsum.grn = specsum.blu = 0.0;
  56.  
  57.     for (lp = lights; lp != (Lightsource *)0; lp = lp->next) {
  58.  
  59.         light_fraction = light_eval(lp, pos, &light_dir);
  60.  
  61.         if (light_fraction > 0.0001) {
  62.             cos_theta = VecDot(light_dir, unit_norm);
  63.             if (cos_theta > 0) {
  64.                 diffsum.red += lp->color.red * cos_theta * light_fraction;
  65.                 diffsum.grn += lp->color.grn * cos_theta * light_fraction;
  66.                 diffsum.blu += lp->color.blu * cos_theta * light_fraction;
  67.             }
  68.         
  69.             cos_theta *= 2.0;
  70.             VecComb(specular, -1.0, light_dir, cos_theta, unit_norm);
  71.             cos_alpha = VecDot(specular, *view_vec);
  72.             if (cos_alpha > 0) {
  73.                 spec_factor = light_fraction * exp(pd->spec_exp
  74.                                                     * log(cos_alpha));  
  75.                 specsum.red += lp->color.red * spec_factor;
  76.                 specsum.grn += lp->color.grn * spec_factor;
  77.                 specsum.blu += lp->color.blu * spec_factor;
  78.             }
  79.         }
  80.     }
  81.  
  82.     color->red = (pd->color.red * (pd->ambient + diffsum.red) 
  83.                   + pd->specular * specsum.red); 
  84.     if (color->red > 1.0) color->red = 1.0;
  85.  
  86.     color->grn = (pd->color.grn * (pd->ambient + diffsum.grn) 
  87.                   + pd->specular * specsum.grn); 
  88.     if (color->grn > 1.0) color->grn = 1.0;
  89.  
  90.     color->blu = (pd->color.blu * (pd->ambient + diffsum.blu) 
  91.                   + pd->specular * specsum.blu);
  92.     if (color->blu > 1.0) color->blu = 1.0;
  93.  
  94.     opacity->red = pd->opacity.red;
  95.     opacity->grn = pd->opacity.grn;
  96.     opacity->blu = pd->opacity.blu;
  97. }
  98.  
  99.  
  100.  
  101.